package com.jiepos.mpos.pay;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import com.jiepos.mpos.common.constant.DBConstant.Table;
import com.jiepos.mpos.common.constant.RspCodeConstant;
import com.jiepos.mpos.common.constant.SystemConstant;
import com.jiepos.mpos.common.dao.AppLogTransJnlsDao;
import com.jiepos.mpos.common.entity.GpsEntity;
import com.jiepos.mpos.common.service.AbrBaseHttpService;
import com.jiepos.mpos.core.util.DateUtil;
import com.jiepos.mpos.core.util.IDFactoryUtil;
import com.jiepos.mpos.core.util.MathUtils;
import com.jiepos.mpos.core.util.StringUtils;

/**
 * 标题: 交易流水业务处理层 
 * 模块: 支付平台 
 * 版权: Copyright (c) 2017 江苏杰博实信息技术有限公司
 * @author 杨剑武
 * @version 1.0
 * @since 2017年9月21日 下午19:47:57 
 * @history（历次修订内容、修订人、修订时间等）
 */
@Service
@SuppressWarnings("unchecked")
public class AppLogTransJnlsPayService extends AbrBaseHttpService  {
	private static final Logger _log = LoggerFactory.getLogger(AppLogTransJnlsPayService.class);
	
	@Autowired
	private AppLogTransJnlsDao appLogTransJnlsDao;
	
	@Autowired
	private MainBusinessService mainBusinessService;
		
	/**
	 * 
	 * 接口: 初始化业务流水
	 * @param payReqMap
	 * @return
	 * @author 杨剑武
	 * @since 2017年10月21日
	 */
	public boolean save(Map<String, String> payReqMap, GpsEntity gpsEntity) {
		_log.info("初始化业务流水请求参数:[payReqMap={},gpsEntity={}]", payReqMap,gpsEntity);
		boolean flag = false;
		try {
			String loc_trace_no = IDFactoryUtil.getId();// 生成本地流水
			String order_no = IDFactoryUtil.getId();// 生成订单号
			if("gate".equals(payReqMap.get("inte_flag")) && !StringUtils.isEmpty(payReqMap.get("order_no"))){
				order_no = payReqMap.get("order_no");// 生成订单号
			}
			StringBuilder builder = new StringBuilder("Insert into ");
			builder.append(Table.T_APP_LOG_TRANS_JNLS);
			builder.append(
					" (TRANS_ID,TRANS_NM,LOC_DT,LOC_TS,CUSTOM_UUID,CUSTOM_NO,CUSTOM_LOGIN_ID,ORDER_NO,SERVICE_UUID,");
			builder.append(
					"SERVICE_PARAM_UUID,LOC_TRACE_NO,SND_DT,SND_TS,PAY_MODE,TRANS_AT,DCFLAG,LOC_STL_DT,TRS_STAT,");
			builder.append(
					"RSPCODE,RSPMSG,LATITUDE,LONGITUDE,COUNTRY,PROVINCE,LOCALITY,SUBLOCALITY,THOROUGHFARE,SUBTHOROUGHFARE,");
			builder.append("LOCALADDRESS,SND_TRACE_NO,CURR_CD,CKSTAT,STLFLG,STLST,ORDER_HANDLE_ST,cycle_no,DTO_BG_URL,DTO_PAGE_URL) ");
			builder.append("values (");
			builder.append("'");
			builder.append(payReqMap.get("trans_id"));// 交易码(终端上送)
			builder.append("','");
			builder.append(payReqMap.get("trans_nm"));// 交易名称(终端上送)
			builder.append("',");
			builder.append("to_char(sysdate,'yyyymmdd')");// 系统日期(数据库时间生成)
			builder.append(",");
			builder.append("to_char(sysdate,'HH24MISS'),");// 系统时间(数据库时间生成)
			builder.append("'");
			builder.append(payReqMap.get("custom_uuid"));// 客户编号(存储过程)
			builder.append("','");
			builder.append(payReqMap.get("custom_no"));// 客户编号(存储过程)
			builder.append("','");
			builder.append(payReqMap.get("login_id"));// 客户编号(存储过程)
			builder.append("','");
			builder.append(order_no);// 订单号(系统生成)
			builder.append("','");
			builder.append(payReqMap.get("service_uuid"));// 业务UUID(终端上送)
			builder.append("','");
			builder.append(payReqMap.get("service_param_uuid"));// 业务参数uuid(终端上送)
			builder.append("','");
			builder.append(loc_trace_no);// 本地流水号(系统生成)
			builder.append("','");
			builder.append(payReqMap.get("snd_dt"));// 交易日期(终端上送)
			builder.append("','");
			builder.append(payReqMap.get("snd_ts"));// 交易时间(终端上送)
			builder.append("','");
			builder.append(!StringUtils.isEmpty(payReqMap.get("pay_mode")) ?  payReqMap.get("pay_mode") : "");// 支付方式(空)
			builder.append("',");
			builder.append(String.valueOf(MathUtils.div(Double.valueOf(payReqMap.get("trans_at")), 100)));// 交易金额(终端上送)
			builder.append(",");
			builder.append("'C',");// 借贷标志(终端上送进行判断)
			builder.append("to_char(sysdate,'yyyymmdd')");// 本地清算日期
			builder.append(",'");
			builder.append(SystemConstant.RSPCODE_SUCCESS);//交易状态(初始化正常状态)
			builder.append("','");
			builder.append(SystemConstant.RSPCODE_XX);// 返回码
			builder.append("','");
			if(!"gate".equals(payReqMap.get("inte_flag"))){
				builder.append(SystemConstant.PRE_ORDER_MSG);
			}else{
				builder.append(SystemConstant.RSPCODE_MSG_XX);
			}
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getLatitude() != null) ? gpsEntity.getLatitude() : "");// 经度(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getLongitude() != null) ? gpsEntity.getLongitude() : "");// 维度(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getCountry() != null) ? gpsEntity.getCountry() : "");// 国家(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getProvince() != null) ? gpsEntity.getProvince() : "");// 省(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getLocality() != null) ? gpsEntity.getLocality() : "");// 市(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getSublocality() != null) ? gpsEntity.getSublocality() : "");// 区(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getThoroughfare() != null) ? gpsEntity.getThoroughfare() : "");// 街道(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getSubthoroughfare() != null) ? gpsEntity.getSubthoroughfare() : "");// 子街道(终端上送)
			builder.append("','");
			builder.append((gpsEntity != null && gpsEntity.getLocaladdress() != null) ? gpsEntity.getLocaladdress() : "");// 地址(终端上送)
			builder.append("','");
			builder.append(!StringUtils.isEmpty(payReqMap.get("snd_trace_no")) ?  payReqMap.get("snd_trace_no") : "");// 受卡方系统跟踪号
			builder.append("',");
			builder.append("'156',");// 币种：156
			builder.append("'0',");// 比对状态
			builder.append("'0',");// 清算标志
			builder.append("'0',");// 清算状态
			builder.append("'1',");// 订单临时处理状态
			builder.append("'000001','");// 批次号
			builder.append(!StringUtils.isEmpty(payReqMap.get("dto_bg_url")) ?  payReqMap.get("dto_bg_url") : "");// 后台通知地址
			builder.append("','");
			builder.append(!StringUtils.isEmpty(payReqMap.get("dto_page_url")) ?  payReqMap.get("dto_page_url") : "");// 前台页面通知地址
			builder.append("')");
			flag = appLogTransJnlsDao.save(builder.toString());
			payReqMap.put("order_no", order_no);
			payReqMap.put("loc_trace_no", loc_trace_no);// 保存本次交易日志主键，利于后续对此条记录进行更新
			if (flag) {
				_log.info("会员[{}]的交易初始化流水[{}]保存成功!", payReqMap.get("custom_no"), loc_trace_no);
			} else {
				payReqMap.put(SystemConstant.RSP_CODE, SystemConstant.RSPCODE_ERROR);
			}
		} catch (Exception e) {
			_log.error("会员初始化流水发生异常", e);
			payReqMap.put(SystemConstant.RSP_CODE, SystemConstant.RSPCODE_ERROR);
		}
		return flag;
	}
	
	/**
	 * 初始化渠道结算流水表
	 */
	public void initLogChannelStl(Map<String, String> infoMap,Map<String, String> standardMap,Map<String, String> paramMap){
		try{
			StringBuffer sb=new StringBuffer();
			sb.append("INSERT INTO ");
			sb.append(Table.T_APP_LOG_CHANNELSTL);
			sb.append(" (channeltl_uuid,custom_no,req_sn_no,loc_dt,loc_ts,loc_trace_no,apply_amt,stlst,rspcode,rspmsg,");
			sb.append("rec_upd_usr_id,rec_crt_ts,order_handle_st)");
			sb.append(" VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?)");
			List paramList = new ArrayList();
			String req_sn_no=IDFactoryUtil.getId();
			paramList.add(IDFactoryUtil.getUUID());//主键
			paramList.add(String.valueOf(infoMap.get("custom_no")));//会员编号
			paramList.add(req_sn_no);//结算请求号
			paramList.add(DateUtil.toString(new Date(), "yyyyMMdd"));//申请日期
			paramList.add(DateUtil.toString(new Date(), "HHmmss"));//申请时间
			paramList.add(String.valueOf(standardMap.get("loc_trace_no")));//交易流水表中的本地流水号
			paramList.add(String.valueOf(MathUtils.div(MathUtils.sub(Double.parseDouble(String.valueOf(standardMap.get("trans_at"))), Double.parseDouble(String.valueOf(standardMap.get("midfee")))), Double.parseDouble("100"), 2)));//申请金额
			paramList.add(SystemConstant.AUDIT_STL_0);//清算状态
			paramList.add(SystemConstant.RSPCODE_XX);//返回码
			paramList.add(SystemConstant.RSPCODE_MSG_XX);//返回描述
			paramList.add(String.valueOf(infoMap.get("custom_no")));//修改的用户标识
			paramList.add(new Timestamp(System.currentTimeMillis()));//创建时间
			paramList.add("1");// 订单临时处理状态
			appLogTransJnlsDao.update(sb.toString(), paramList);
			paramMap.put("req_sn_no", req_sn_no);
		} catch (Exception e) {
			_log.error("初始化渠道结算流水发生异常", e);			
		}
	}
	
	/**
	 * 查询结算流水相关信息
	 * @param req_sn_no
	 * @return
	 */
	public Map<String, String> selectLogChannelStl(String req_sn_no){
		try{
			StringBuffer sb=new StringBuffer();
			sb.append("select t1.custom_no,t1.req_sn_no,t1.loc_dt,t1.loc_ts,t1.loc_trace_no,t1.channel_trace_no,t2.trf_channel_id,");
			sb.append("t2.trans_at,t2.complete_dt,t2.midfee,t2.rcvfee from ");
			sb.append(Table.T_APP_LOG_CHANNELSTL);	
			sb.append(" t1 inner join  t_app_log_trans_jnls t2 on t1.loc_trace_no=t2.loc_trace_no ");
			sb.append(" where t1.req_sn_no='").append(req_sn_no).append("'");
			
			List<Map<String, String>> list=appLogTransJnlsDao.queryForList(sb.toString());
			if(list==null||list.size()==0){
				return new HashMap<String,String>();
			}else{
				return list.get(0);
			}
		} catch (Exception e) {
			_log.error("查询结算流水相关信息发生异常", e);
			return new HashMap();
		}
	}
	/**
	 * 
	 * 接口: 更新流水(主业务流程校验)
	 * @param payReqMap
	 * @param value
	 * @return
	 * @since 2017年10月21日
	 */
	public void update(Map<String, String> payReqMap, String value, String desc) {
		_log.info("更新流水参数:[map={},value={},desc={}]", payReqMap, value, desc);
		try {
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String> values = new HashMap<String, String>();
			Assert.notNull(payReqMap.get("loc_trace_no"));
			params.put("loc_trace_no", payReqMap.get("loc_trace_no"));//本地交易流水
			values.put("trs_stat", SystemConstant.RSPCODE_ERROR);// 交易状态99
			values.put("rspcode", value);// 响应码
			values.put("rspmsg", desc);// 响应描述
			values.put("service_ins_uuid",payReqMap.get("service_ins_uuid"));// 业务机构UUID
			values.put("act_out_no", payReqMap.get("act_out_no"));
			values.put("act_in_no", payReqMap.get("act_in_no"));
			values.put("card_bin", payReqMap.get("card_bin"));
			values.put("card_name", payReqMap.get("card_name"));
			values.put("card_ins_cd", payReqMap.get("card_ins_cd"));
			values.put("card_ins_nm", payReqMap.get("card_ins_nm"));
			values.put("crd_nature", payReqMap.get("crd_nature"));
			values.put("service_minfee",payReqMap.get("service_minfee") );// 贷记卡最小手续费
			values.put("service_disc", payReqMap.get("service_disc"));// 贷记卡扣率
			values.put("service_disc_maxfee",payReqMap.get("service_disc_maxfee") );// 贷记卡最大手续费
			values.put("service_attachfee",payReqMap.get("service_attachfee"));// 贷记卡附加手续费
			if (appLogTransJnlsDao.update(params, values)) {
				_log.info("本地流水号为[{}]记录更新成功!", payReqMap.get("loc_trace_no"));
			} else {
				payReqMap.put(SystemConstant.RSP_CODE, SystemConstant.RSPCODE_ERROR);
			}
			_log.info("交易错误异步通知管理系统 loc_trace_no=" + payReqMap.get("loc_trace_no"));
			mainBusinessService.asyncNotifyMpos(payReqMap.get("loc_trace_no"));
		} catch (Exception e) {
			payReqMap.put(SystemConstant.RSP_CODE, SystemConstant.RSPCODE_ERROR);
			_log.error("本地流水号为[{}]记录更新发生异常!", payReqMap.get("loc_trace_no"), e);
		}
	}
	/**
	 * 更新流水(受卡方所在地日期、受卡方所在地时间、系统跟踪号等信息)
	 * 
	 * @param map
	 */
	public boolean update(Map<String, String> payReqMap,GpsEntity gpsEntity) {
		_log.info("更新业务流水请求的参数:[payReqMap={}]",payReqMap);
		try {
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String> values = new HashMap<String, String>();
			Assert.notNull(payReqMap.get("loc_trace_no"));
			params.put("loc_trace_no", payReqMap.get("loc_trace_no"));//本地交易流水
			values.put("trans_id", payReqMap.get("trans_id"));
			values.put("trans_nm ", payReqMap.get("trans_nm"));
			values.put("snd_dt", payReqMap.get("snd_dt"));
			values.put("snd_ts ", payReqMap.get("snd_ts"));
			values.put("snd_trace_no", payReqMap.get("snd_trace_no"));
			values.put("rspmsg", "处理中");
			values.put("latitude",gpsEntity.getLatitude());// 经度(终端上送)
			values.put("longitude",gpsEntity.getLongitude());// 维度(终端上送)
			values.put("country",gpsEntity.getCountry());// 国家(终端上送)
			values.put("province",gpsEntity.getProvince());// 省(终端上送)
			values.put("locality",gpsEntity.getLocality());// 市(终端上送)
			values.put("sublocality",gpsEntity.getSublocality());// 区(终端上送)
			values.put("thoroughfare",gpsEntity.getThoroughfare());// 街道(终端上送)
			values.put("subthoroughfare",gpsEntity.getSubthoroughfare());// 子街道(终端上送)
			values.put("localaddress", gpsEntity.getLocaladdress());//详细地址
			if (appLogTransJnlsDao.update(params, values)) {
				_log.info("本地流水号为[{}]记录更新(交易码、交易名称、受卡方所在地日期、受卡方所在地时间、受卡方系统跟踪号)成功！", payReqMap.get("loc_trace_no"));
				return true;
			} else {
				payReqMap.put(SystemConstant.RSP_CODE, SystemConstant.RSPCODE_ERROR);
			}
		} catch (Exception e) {
			payReqMap.put(SystemConstant.RSP_CODE, SystemConstant.RSPCODE_ERROR);
			_log.error("本地流水号为[{}]记录更新发生异常！", payReqMap.get("loc_trace_no"),e);
		}
		return false;
	}

	/**
	 * 
	 * 接口: 更新流水信息
	 * @param payReqMap 
	 * @param routeMap
	 * @since 2017年11月1日
	 */
	public boolean update(Map<String, String> payReqMap, Map<String, String> routeMap) {
		_log.info("更新业务流水请求的参数:[请求map={},路由map={}]", payReqMap,routeMap);
		try {
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String> values = new HashMap<String, String>();
			Assert.notNull(payReqMap.get("loc_trace_no"));
			params.put("loc_trace_no", payReqMap.get("loc_trace_no"));//本地交易流水
			values.put("trf_channel_id", routeMap.get("channel_No"));// 转发商户号
			values.put("trf_term_id", routeMap.get("trf_term_id"));// 转发终端号
			values.put("ins_uuid", routeMap.get("route_ins_uuid"));// 路由机构UUID
			values.put("acq_ins_cd", routeMap.get("acq_ins_cd"));
			values.put("costfee", routeMap.get("costfee"));// 成本手续费
			values.put("midfee", routeMap.get("midfee"));// 商户手续费
			values.put("trf_mchnt_cd", routeMap.get("trf_mchnt_cd"));
			values.put("service_ins_uuid", payReqMap.get("service_ins_uuid"));// 业务机构UUID
			values.put("act_out_no", payReqMap.get("act_out_no"));
			values.put("act_in_no", payReqMap.get("act_in_no"));
			values.put("crd_exp", payReqMap.get("crd_exp"));
			values.put("card_bin", payReqMap.get("card_bin"));
			values.put("card_name", payReqMap.get("card_name"));
			values.put("card_ins_cd", payReqMap.get("card_ins_cd"));
			values.put("card_ins_nm", payReqMap.get("card_ins_nm"));
			values.put("crd_nature", payReqMap.get("crd_nature"));
			values.put("service_minfee", payReqMap.get("service_minfee"));// 贷记卡最小手续费
			values.put("service_disc", payReqMap.get("service_disc"));// 贷记卡扣率
			values.put("service_disc_maxfee", payReqMap.get("service_disc_maxfee"));// 贷记卡最大手续费
			values.put("service_attachfee", payReqMap.get("service_attachfee"));// 贷记卡附加手续费
			payReqMap.put("trf_mchnt_cd", routeMap.get("trf_mchnt_cd"));//渠道商户号
			payReqMap.put("trf_term_id", routeMap.get("trf_term_id"));//渠道终端号
			payReqMap.put("master_key", routeMap.get("master_key"));//渠道加密密钥
			payReqMap.put("midfee", routeMap.get("midfee"));//手续费
			payReqMap.put("channel_No", routeMap.get("channel_No"));//通到编号
			if (appLogTransJnlsDao.update(params, values)) {
				_log.info("本地流水号为[{}]记录(业务信息)更新成功！", payReqMap.get("loc_trace_no"));
				return true;
			}
		} catch (Exception e) {
			_log.error("本地流水号为[{}]记录(业务信息)更新发生异常！", payReqMap.get("loc_trace_no"), e);
		}
		return false;
	}

	/**
	 * 
	 * 功能描述:根据订单号和客户编号查询对应的本地流水
	 * 
	 * @param custom_no
	 * @param order_no
	 * @return
	 */
	public boolean getLocTraceNo(Map<String, String> payReqMap) {
		try {
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String> values = new HashMap<String, String>();
			Assert.notNull(payReqMap.get("order_no"));
			params.put("order_no", payReqMap.get("order_no"));
			params.put("custom_no", payReqMap.get("custom_no"));
			values.put("loc_trace_no", "loc_trace_no");
			values.put("trans_at", "trans_at");
			values.put("snd_trace_no", "snd_trace_no");
			values.put("rspcode", "rspcode");
			Map<String, Object> dataMap = appLogTransJnlsDao.getTranInfo(params, values);
			_log.info("查询对应的本地流水信息map=[{}]", dataMap);
			if (!StringUtils.isEmpty(dataMap)) {
				if(SystemConstant.RSPCODE_CLOSE.equals(String.valueOf(dataMap.get("rspcode")))){
					payReqMap.put(SystemConstant.RSP_CODE, RspCodeConstant.RSPCODE_300064);
					return false;
				}
				payReqMap.put("loc_trace_no", String.valueOf(dataMap.get("loc_trace_no")));
				payReqMap.put("trans_at", String.valueOf(dataMap.get("trans_at")));
				if (StringUtils.isEmpty(dataMap.get("snd_trace_no"))) {// 预下单
					_log.info("会员[{}],订单号[{}]对应的本地流水号[{}]交易金额[{}]！", payReqMap.get("custom_no"),
							payReqMap.get("order_no"), dataMap.get("loc_trace_no"), dataMap.get("trans_at"));
					return true;
				} else {
					Assert.notNull(payReqMap.get("snd_trace_no"));
					if (!appLogTransJnlsDao.getSndTraceNo(payReqMap.get("custom_no"), payReqMap.get("snd_trace_no"),String.valueOf(dataMap.get("loc_trace_no")).substring(0, 8))) {
						String loc_trace_no = IDFactoryUtil.getId();// 生成本地流水
						StringBuilder builder = new StringBuilder();
						builder.append(
								"Insert into T_APP_LOG_TRANS_JNLS(TRANS_ID,TRANS_NM,LOC_DT,LOC_TS,INS_UUID,CUSTOM_UUID,CUSTOM_NO,CUSTOM_LOGIN_ID,ORDER_NO,SERVICE_UUID,SERVICE_PARAM_UUID,LOC_TRACE_NO,");
						builder.append(
								"SND_TRACE_NO,SND_DT,SND_TS,SND_CYCLE_NO,TRF_CHANNEL_ID,TRF_CYCLE_NO,TRF_MCHNT_CD,TRF_TERM_ID,TRF_TRACE_NO,PAY_MODE,ACT_OUT_NO,ACT_IN_NO,CRD_MEDIUM,CRD_NATURE,TRANS_AT,STL_AMT,");
						builder.append(
								"DCFLAG,CRD_EXP,LOC_STL_DT,STL_DT,CRD_SEQ_NO,REF_NO,AUTH_NO,TRS_STAT,RSPCODE,RSPMSG,LATITUDE,LONGITUDE,COUNTRY,LOCALITY,SUBLOCALITY,THOROUGHFARE,SUBTHOROUGHFARE,LOCALADDRESS,APN,");
						builder.append(
								"ACQ_INS_CD,ISS_INS_CD1,CURR_CD,ACT_TP,COSTFEE,MIDFEE,SNDFEE,RCVFEE,CKSTAT,STLFLG,STLST,COMPLETE_DT,COMPLETE_TS,SERVICE_DISC,SERVICE_DISC_MAXFEE,RISK_STAT,RISK_INSUUID,RISK_TYPE,");
						builder.append(
								"RISK_DESC,SERVICE_MINFEE,SERVICE_ATTACHFEE,ORDER_HANDLE_ST,SERVICE_INS_UUID,CYCLE_NO,PROVINCE,IS_SEND_RAND)");
						builder.append(
								"select TRANS_ID,TRANS_NM,to_char(sysdate,'yyyymmdd'),to_char(sysdate,'HH24MISS'),INS_UUID,CUSTOM_UUID,CUSTOM_NO,CUSTOM_LOGIN_ID,ORDER_NO,SERVICE_UUID,SERVICE_PARAM_UUID,'");
						builder.append(loc_trace_no);
						builder.append("','");
						builder.append(payReqMap.get("snd_trace_no"));
						builder.append(
								"',SND_DT,SND_TS,SND_CYCLE_NO,TRF_CHANNEL_ID,TRF_CYCLE_NO,TRF_MCHNT_CD,TRF_TERM_ID,null,PAY_MODE,ACT_OUT_NO,ACT_IN_NO,CRD_MEDIUM,CRD_NATURE,TRANS_AT,STL_AMT,DCFLAG,CRD_EXP,");
						builder.append("LOC_STL_DT,STL_DT,CRD_SEQ_NO,REF_NO,AUTH_NO,'");
						builder.append(SystemConstant.RSPCODE_SUCCESS);
						builder.append("','");
						builder.append(SystemConstant.RSPCODE_XX);
						builder.append("','处理中',LATITUDE,LONGITUDE,COUNTRY,LOCALITY,SUBLOCALITY,THOROUGHFARE,SUBTHOROUGHFARE,LOCALADDRESS,APN,ACQ_INS_CD,ISS_INS_CD1,");
						builder.append(
								"CURR_CD,ACT_TP,COSTFEE,MIDFEE,SNDFEE,RCVFEE,CKSTAT,'0','0',null,null,SERVICE_DISC,SERVICE_DISC_MAXFEE,RISK_STAT,RISK_INSUUID,RISK_TYPE,RISK_DESC,SERVICE_MINFEE,");
						builder.append("SERVICE_ATTACHFEE,'1',SERVICE_INS_UUID,CYCLE_NO,PROVINCE,null ");
						builder.append("from T_APP_LOG_TRANS_JNLS where LOC_TRACE_NO = '");
						builder.append(String.valueOf(dataMap.get("loc_trace_no")));
						builder.append("' and (loc_dt = to_char(sysdate-1,'yyyymmdd') or loc_dt = to_char(sysdate,'yyyymmdd') or loc_dt = to_char(sysdate+1,'yyyymmdd'))");
						if (appLogTransJnlsDao.save(builder.toString())) {
							params.clear();
							values.clear();
							params.put("loc_trace_no", payReqMap.get("loc_trace_no"));// 本地交易流水
							params.put("rspcode", SystemConstant.RSPCODE_XX);//(避免已经是失败状态的)
							values.put("trs_stat", SystemConstant.RSPCODE_ERROR);// 交易状态99
							values.put("rspcode", SystemConstant.RSPCODE_ERROR);
							values.put("rspmsg", SystemConstant.RSPCODE_ERROR_MSG);
							appLogTransJnlsDao.update(params, values);// 将上条记录更新为交易失败
							payReqMap.put("loc_trace_no", loc_trace_no);
							_log.info("会员[{}],订单号[{}]重复支付生成的本地流水号为[{}],交易金额为[{}]！", payReqMap.get("custom_no"),
									payReqMap.get("order_no"), loc_trace_no, dataMap.get("trans_at"));
							return true;
						}
					} else {
						_log.warn("会员[{}],订单号[{}]重复支付失败,系统跟踪号已存在!(原流水号为[{}])", payReqMap.get("custom_no"),
								payReqMap.get("order_no"), dataMap.get("loc_trace_no"));
					}
				}
			} else {
				_log.warn("会员[{}],订单号[{}]查询对应的流水信息不存在!", payReqMap.get("custom_no"), payReqMap.get("order_no"));
			}
		} catch (Exception e) {
			_log.error("根据订单号和客户编号查询对应的本地流水发生异常", e);
		}
		return false;
	}

	/**
	 * 定时查询时，处理交易状态未知的交易
	 * 
	 * @return
	 */
	public List<Map<String, String>> getErrStatList() {

		return appLogTransJnlsDao.getErrStatList();
	}
	/**
	 * 查询处理中的清算流水
	 * @return
	 */
	public List<Map<String, String>> getLogChnStlList() {

		return appLogTransJnlsDao.getLogChnStlList();
	}

	/**
	 * 接口: 更新订单处理中间状态
	 * @since 2017年10月31日
	 */
	public void update(String loc_dt,String loc_trace_no, String stlst,String trs_stat, String rspcode, String rspmsg, String order_handle_st, 
			String complete_dt, String complete_ts,String trf_trace_no, String midfee, String rcvfee, String stlflg) {
		try {
			Map<String, String> params = new HashMap<String, String>();
			Map<String, String> values = new HashMap<String, String>();
			Assert.notNull(loc_trace_no);
			params.put("loc_trace_no", loc_trace_no);
			params.put("loc_dt", loc_dt);
			values.put("order_handle_st", order_handle_st);
			if (!StringUtils.isEmpty(trs_stat)) {
				values.put("trs_stat",trs_stat);
			}
			if (!StringUtils.isEmpty(rspcode) && !StringUtils.isEmpty(rspmsg)) {
				values.put("rspcode", rspcode);
				values.put("rspmsg", rspmsg);
			}
			if (!StringUtils.isEmpty(stlst)) {
				values.put("stlst", stlst);
			}
			
			if (!StringUtils.isEmpty(complete_dt)) {
				values.put("complete_dt", complete_dt);
			}
			if (!StringUtils.isEmpty(complete_ts)) {
				values.put("complete_ts", complete_ts);
			}
			if (!StringUtils.isEmpty(trf_trace_no)) {
				values.put("trf_trace_no", trf_trace_no);
			}
			if (!StringUtils.isEmpty(midfee)) {
				values.put("midfee", midfee);
			}
			if (!StringUtils.isEmpty(rcvfee)) {
				values.put("rcvfee", rcvfee);
			}
			if (!StringUtils.isEmpty(stlflg)) {
				values.put("stlflg", stlflg);
			}
			
			//判断当交易流水处理状态已经是完成状态就不更新啦
			Map<String,String> dataMap = getTranInfo(loc_trace_no);
			if(!"3".equals(dataMap.get("order_handle_st"))){
				appLogTransJnlsDao.update(params, values);
			}
			_log.info("本地流水号为[{}]记录更新成功！", loc_trace_no);
		} catch (Exception e) {
			_log.error("本地流水号为[{}]记录更新发生异常！", loc_trace_no, e);
		}
	}
	

	/**
	 * 根据订单号查询订单信息
	 * 
	 * @param orderNo
	 * @param loc_trace_no
	 * @return
	 */
	public Map<String,String> getTransJnlsByNo(String orderNo, String loc_trace_no,String trace_no,String inte_flag) {
		_log.info("根据订单号查询流水号={},订单号={},交易流水号={}",loc_trace_no ,orderNo,trace_no);
		try{			
			StringBuffer sb = new StringBuffer();		
			sb.append("select t1.order_no,t1.trans_at,t1.loc_trace_no,t1.complete_dt,t1.complete_ts,t1.midfee,t1.costfee,t1.stl_amt,");		
			sb.append( "t1.stlst,t1.trs_stat,t1.custom_uuid,t1.loc_dt,");
			sb.append("t1.rspcode,t1.rspmsg,t1.stl_dt,t1.trf_channel_id,t1.trf_mchnt_cd,t1.trf_term_id,t1.custom_no,");	
			sb.append("t1.stl_dt,t1.pay_dt,t1.pay_ts from ");
			sb.append(Table.T_APP_LOG_TRANS_JNLS);
			sb.append(" t1 ");			
			sb.append(" where 1=1");
			if(!StringUtils.isBlank(loc_trace_no)){
				sb.append(" and t1.loc_trace_no='").append(loc_trace_no).append("'");
				sb.append(" and (t1.loc_dt = to_char(sysdate,'yyyymmdd') or t1.loc_dt = to_char(sysdate-1,'yyyymmdd'))");
			}else if("gate".equals(inte_flag) && !StringUtils.isBlank(orderNo)){
				sb.append(" and t1.order_no='").append(orderNo).append("'");
			}else if(!StringUtils.isBlank(orderNo)&&!StringUtils.isBlank(trace_no)){
				sb.append(" and t1.order_no='").append(orderNo).append("'");
				sb.append(" and t1.snd_trace_no='").append(trace_no).append("'");
				sb.append(" and (t1.loc_dt = to_char(sysdate,'yyyymmdd') or t1.loc_dt = to_char(sysdate-1,'yyyymmdd'))");
			}			
			
			List<Map<String,String>> result = appLogTransJnlsDao.queryForList(sb.toString());
			if(result==null||result.size()==0){
				return new HashMap<String,String>();
			}
			Map<String,String> repMap=result.get(0);
			repMap.put("gate_trans_at", String.valueOf(repMap.get("trans_at")));
			//金额元转分
			if(!StringUtils.isBlank(String.valueOf(repMap.get("trans_at")))){			
				repMap.put("trans_at", String.valueOf(MathUtils.mul(Double.parseDouble(String.valueOf(repMap.get("trans_at"))), Double.parseDouble("100"))));
			}else{
				repMap.put("trans_at", "0");
			}
			repMap.put("gate_midfee", String.valueOf(repMap.get("midfee")));
			if(!StringUtils.isBlank(String.valueOf(repMap.get("midfee")))){			
				repMap.put("midfee", String.valueOf(MathUtils.mul(Double.parseDouble(String.valueOf(repMap.get("midfee"))), Double.parseDouble("100"))));
			}else{
				repMap.put("midfee", "0");
			}
			repMap.put("gate_stl_amt", String.valueOf(repMap.get("stl_amt")));
			if(!StringUtils.isBlank(String.valueOf(repMap.get("stl_amt")))){			
				repMap.put("stl_amt", String.valueOf(MathUtils.mul(Double.parseDouble(String.valueOf(repMap.get("stl_amt"))), Double.parseDouble("100"))));
			}else{
				repMap.put("stl_amt", "0");
			}
			return repMap;
		}catch(Exception e){
			_log.error("流水号={},订单号={},交易流水号={}查询流水异常！",loc_trace_no ,orderNo,trace_no);
			return new HashMap();
		}
		
	}

	/**
	 * 异步通知更新流水
	 * 
	 * @param map
	 */
	public void updateByNotice(Map<String, String> map) {
		_log.info("异步通知更新流水请求的map=[{}]", map);
		try {
			StringBuilder sb = new StringBuilder();
			sb.append("update ");
			sb.append(Table.T_APP_LOG_TRANS_JNLS);
			sb.append(
					" set trs_stat=?,rspcode=?,rspmsg=?,stlst=?,stl_dt=?,stl_amt=?,trf_trace_no=?,complete_dt=?,complete_ts=? ");
			sb.append(" where loc_trace_no=? ");
			List paramList = new ArrayList();
			paramList.add(map.get("trs_stat"));
			paramList.add(map.get("rspcode"));
			paramList.add(map.get("rspmsg"));
			paramList.add(map.get("stlst"));
			paramList.add(map.get("stl_dt"));
			paramList.add(map.get("stl_amt"));
			paramList.add(map.get("trf_trace_no"));
			paramList.add(map.get("complete_dt"));
			paramList.add(map.get("complete_ts"));
			paramList.add(map.get("loc_trace_no"));
			appLogTransJnlsDao.update(sb.toString(), paramList);
		} catch (Exception e) {
			_log.error("异步通知更新交易流水发生异常", e);
		}
	}	

	/**
	 * 
	* 功能描述:根据本地系统流水查询客户UUID及交易金额
	* @return
	 */
	public Map<String, String> getTranInfo(String loc_trace_no) {
		Map<String, String> infoMap = new HashMap<String, String>();
		Map<String, String> params = new HashMap<String, String>();
		Map<String, String> values = new HashMap<String, String>();
		Assert.notNull(loc_trace_no);
		params.put("loc_trace_no", loc_trace_no);
		values.put("trf_mchnt_cd", "trf_mchnt_cd");
		values.put("trf_channel_id", "trf_channel_id");
		values.put("trf_term_id", "trf_term_id");
		values.put("custom_no", "custom_no");
		values.put("custom_uuid", "custom_uuid");
		values.put("trans_at", "trans_at");
		values.put("midfee", "midfee");
		values.put("stlst", "stlst");
		values.put("rspcode", "rspcode");
		values.put("rspmsg", "rspmsg");
		values.put("rspmsg", "rspmsg");
		values.put("order_handle_st", "order_handle_st");
		values.put("loc_dt", "loc_dt");
		values.put("loc_ts", "loc_ts");
		values.put("complete_dt", "complete_dt");
		values.put("complete_ts", "complete_ts");
		values.put("trf_mchnt_cd", "trf_mchnt_cd");
		values.put("act_out_no", "act_out_no");
		values.put("trf_channel_id", "trf_channel_id");
		Map<String, Object> data = appLogTransJnlsDao.getTranInfo(params, values);
		_log.info("[{}]流水号对应的流水信息为:[{}]", loc_trace_no, data);
		if (!StringUtils.isEmpty(data)) {
			infoMap.put("trf_mchnt_cd", String.valueOf(data.get("trf_mchnt_cd")));// 商户编号
			infoMap.put("trf_channel_id", String.valueOf(data.get("trf_channel_id")));
			infoMap.put("trf_term_id", String.valueOf(data.get("trf_term_id")));// 终端编号（渠道）
			infoMap.put("custom_no", String.valueOf(data.get("custom_no")));// 会员编号
			infoMap.put("custom_uuid", String.valueOf(data.get("custom_uuid")));
			infoMap.put("trans_at", String.valueOf(data.get("trans_at")));
			infoMap.put("midfee", String.valueOf(data.get("midfee")));
			infoMap.put("stlst", String.valueOf(data.get("stlst")));
			infoMap.put("rspcode", String.valueOf(data.get("rspcode")));
			infoMap.put("rspmsg", String.valueOf(data.get("rspmsg")));
			infoMap.put("order_handle_st", String.valueOf(data.get("order_handle_st")));
			infoMap.put("loc_dt", String.valueOf(data.get("loc_dt")));
			infoMap.put("loc_ts", String.valueOf(data.get("loc_ts")));
			infoMap.put("trf_mchnt_cd", String.valueOf(data.get("trf_mchnt_cd")));
			infoMap.put("act_out_no", String.valueOf(data.get("act_out_no")));
			infoMap.put("trf_channel_id", String.valueOf(data.get("trf_channel_id")));
		}
		return infoMap;
	}

	/**
	 * 关闭订单
	 */
	public void closeOrder(){
		StringBuffer sb=new StringBuffer();
		sb.append("select CODE_TP,CODE_VAL from ").append(Table.T_APP_CODE_LIST).append(" where REC_ST !='0' and ")
		.append(" CODE_TP='CLOSE_ORDER_TIME'");
		List<Map<String,String>> result =appLogTransJnlsDao.queryForList(sb.toString());
		String time="";
		if(result==null||result.size()==0){
			time=SystemConstant.CLOSE_ORDER_DEFAULT_TIME;//默认120分钟
		}else{
			time=String.valueOf(result.get(0).get("CODE_VAL"));
		}
		String rspmsg=String.valueOf(super.getRspCodeListMap().get(SystemConstant.RSPCODE_CLOSE));
		
		List<String> locTraceNos = appLogTransJnlsDao.closeOrderRegular(time,SystemConstant.RSPCODE_CLOSE,SystemConstant.RSPCODE_CLOSE,rspmsg);
		for(String locTraceNo : locTraceNos){
			_log.info("关闭订单异步通知管理系统 loc_trace_no=" + locTraceNo);
			try {
				mainBusinessService.asyncNotifyMpos(locTraceNo);
			} catch (Exception e) {
				_log.info("关闭订单异步通知管理系统失败");
			}
		}
	}
	
	/**
	 * 获取关闭订单时间
	 * @return
	 */
	public String getCloseOrderTime(){
		StringBuffer sb=new StringBuffer();
		sb.append("select CODE_TP,CODE_VAL from ").append(Table.T_APP_CODE_LIST).append(" where REC_ST !='0' and ")
		.append(" CODE_TP='CLOSE_ORDER_TIME'");
		List<Map<String,String>> result =appLogTransJnlsDao.queryForList(sb.toString());
		String time="";
		if(result==null||result.size()==0){
			time=SystemConstant.CLOSE_ORDER_DEFAULT_TIME;//默认120分钟
		}else{
			time=String.valueOf(result.get(0).get("CODE_VAL"));
		}
		return time;
	}
	
	/**
	 * 
	 * 接口: 更新交易流水中短信接收标志
	 * @param loc_trace_no
	 * @return
	 * @since 2018年1月9日
	 */
	public void  updateTraceNoIsSendRand(String loc_trace_no) throws Exception{
		if(!appLogTransJnlsDao.updateTraceNoIsSendRand(loc_trace_no)){
			throw new Exception("更新交易流水中短信接收标志发生异常");
		}
	}
	
	public void updateTraceNo(String loc_trace_no,String loc_dt,String loc_ts) throws Exception{
		if(!appLogTransJnlsDao.updateTraceNo(loc_trace_no,loc_dt,loc_ts)){
			throw new Exception("交易结束更新交易状态发生异常");
		}
	}
	
	/**
	 * 获取异步通知失败的流水
	 * @return
	 */
	public List<Map<String, String>> getNotifyFailList() {

		return appLogTransJnlsDao.getNotifyFailList();
	}

}
